package view;

import controller.MyController;
import entity.TestsPaper;
import lombok.SneakyThrows;
import service.TestsOpt;
import service.UserOpt;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 测试界面
 */
public class TestsMain extends JFrame implements ActionListener {
    JButton btn1,btn2,btn3;
    JCheckBox[] b;      // 选项
    JLabel label1,label2,label3;     // label3放置倒计时标签
    JPanel panel1,panel2,panel3,panel4,panel5,panel6;
    String testsName;           //试卷名称
    JTextArea area;
    JScrollPane scrollPane;
    TestsPaper paper;
    Font font;
    int testNum;     // 当前题目编号
    int testsSum;    // 题目总数
    int testTime;    // 考试时间（分钟）
    Date endTime;    // 截至时间
    Timer timer;     // 倒计时监听器
    int score;       // 考试成绩
    String username;
    Home home;
    Map<Integer,Integer> scoreMap;     // 存储用户各个正确题的成绩
    int oneScore;    // 单个分数
    Map<Integer,String> optStatus;     // 保留用户各个题的选择状态
    public TestsMain(Home home,String name) throws IOException {
        super("考试主页");
        ImageIcon icon = new ImageIcon("src\\main\\resources\\img\\icon5.png");
        this.setIconImage(icon.getImage());
        this.username = name;
        this.home = home;
        this.home.setVisible(false);
        testNum = 1;
        oneScore = 5;
        testsPaperInit(testNum);
        testTime = 1;
        String info = "<html><body>姓名："+name+"&emsp;&emsp;考试时间："+testTime+"分钟&emsp;&emsp;考试科目："+testsName+"</body></html>";
        testsSum = MyController.getTotalSum();
        String ms = "第"+testNum+"题/共"+testsSum+"题";
        score = 0;           // 初始化测试成绩为0
        scoreMap = new HashMap<>();
        optStatus = new HashMap<>();
        label2 = new JLabel(ms);
        label1 = new JLabel(info);
        panel1 = new JPanel();

        endTime = getEndTime(new Date(),testTime);
        label3 = new JLabel(getTimeRemain());
        label3.setFont(new Font("微软雅黑",Font.BOLD,15));
        timer.start();
        panel5 = new JPanel();
        panel5.setLayout(new FlowLayout());
        panel5.add(label3);
        panel1.add(label1);

        panel6 = new JPanel();
        panel6.setLayout(new BorderLayout());
        panel6.add(panel1,BorderLayout.CENTER);
        panel6.add(panel5,BorderLayout.SOUTH);
        panel1.setBackground(Color.PINK);
        panel5.setBackground(Color.PINK);

        area = new JTextArea();
        font = new Font("Serif",0,15);
        area.setText("【"+paper.getTestsType()+"】"+paper.getStem()+"\n"+paper.getOptions());
        area.setFont(font);
        area.setLineWrap(true);
        area.setWrapStyleWord(true);
        area.setEditable(false);
        scrollPane = new JScrollPane(area);
        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        btn1 = new JButton("上一题");
        if (testNum == 1){
            btn1.setEnabled(false);
        }
        btn2 = new JButton("下一题");
        if (testNum == testsSum){
            btn2.setEnabled(false);
        }
        btn3 = new JButton("交卷");
        btn1.addActionListener(this);
        btn2.addActionListener(this);
        btn3.addActionListener(this);
        panel2 = new JPanel();
        panel2.setLayout(new FlowLayout());
        panel2.add(btn1);
        panel2.add(btn2);
        panel2.add(label2);
        panel2.add(btn3);
        panel2.setBackground(Color.ORANGE);


        b = new JCheckBox[4];
        panel3 = new JPanel();
        panel3.setLayout(new FlowLayout());
        String[] keys = {"A","B","C","D"};
        for (int i=0;i<4;i++){
            b[i] = new JCheckBox(keys[i]);
            panel3.add(b[i]);
        }


        panel4 = new JPanel();
        panel4.setLayout(new BorderLayout());
        panel4.add(panel3,BorderLayout.CENTER);
        panel4.add(panel2,BorderLayout.SOUTH);

        this.setLayout(new BorderLayout());
        this.add(panel6,BorderLayout.NORTH);
        this.add(scrollPane,BorderLayout.CENTER);
        this.add(panel4,BorderLayout.SOUTH);
        this.setVisible(true);
        this.setBounds(500,250,600,450);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    /**
     * 返回主页
     */
    public void ReHome() throws IOException {
        // 更新用户成绩
        MyController.updUserScore(this.username,this.testsName,this.score);
        this.setVisible(false);
        this.home.setVisible(true);
        this.timer.stop();
    }
    /**
     * 试卷初始化
     * @param Num
     */
    public void testsPaperInit(int Num){        // 试题数据初始化
        this.testsName = "java测试";
        if (Num >= 1){
            paper = MyController.getTestByRow(Num-1);
        }else{
            System.exit(0);
        }
        this.timer = new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (!label3.getText().equals("剩余时间: 0:0:0")){
                    label3.setText(getTimeRemain());
                }else {
                    if (resultJudge()){
                        scoreMap.put(paper.getRow(),oneScore);
                    }
                    getSumScore();      // 获取总成绩
                    JOptionPane.showMessageDialog(null, "考试时间已到,您的测试成绩为："+score);
                    try {
                        ReHome();     // 返回主页
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                    return;
                }
            }
        });
    }

    /**
     * 获取考试结束时间
     * @param nowDate
     * @param testTime
     * @return
     */
    public Date getEndTime(Date nowDate,int testTime){
        Calendar c = Calendar.getInstance();
        c.setTime(nowDate);
        c.add(Calendar.MINUTE,testTime);
        return c.getTime();
    }

    /**
     * 获取剩余时间标签字符串
     * @return
     */
    public String getTimeRemain(){
        long r = this.endTime.getTime() - new Date().getTime();
        long t = r / 1000;
        long h = t / 3600;
        long m = t % 3600 / 60;
        long s = t % 3600 % 60;
        return "剩余时间: "+h+":"+m+":"+s;
    }

    /**
     * 试题结果判断
     * @return
     */
    public boolean resultJudge(){
        StringBuilder result = new StringBuilder();

        for (int i=0;i<4;i++){
            if (b[i].isSelected()){
                result.append(b[i].getText());
            }
        }

        // 保存用户当前题的选择状态
        optStatus.put(this.paper.getRow(), result.toString());

        String correctResult = this.paper.getCorrectOpt();
        if (result.length() == correctResult.length()){
            String[] k = result.toString().split("");
            for (String a:k){
                if (!correctResult.contains(a)){
                    return false;
                }
            }
            return true;
        }
        return false;
    }

    /**
     * 获取总成绩
     * @return
     */
    public int getSumScore(){
        int sum = 0;
        for (Map.Entry<Integer,Integer> entry:scoreMap.entrySet()){
            sum += entry.getValue();
        }
        score = sum;
        return score;
    }

    @SneakyThrows
    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == btn1){
            if (testNum == 1){
                btn1.setEnabled(false);
            }else {
                testNum--;
                this.btn2.setEnabled(true);
                // 进行翻页时计算本题的成绩
                if (resultJudge()){
                    scoreMap.put(paper.getRow(),oneScore);
                }
                this.paper = MyController.getTestByRow(testNum-1);          // 更新试卷
                String ms = "第"+testNum+"题/共"+testsSum+"题";
                this.label2.setText(ms);
                this.area.setText("【"+paper.getTestsType()+"】"+paper.getStem()+"\n"+paper.getOptions());
                // 刷新多选框
                if (optStatus.containsKey(this.paper.getRow()) && (!optStatus.get(this.paper.getRow()).equals(""))){
                    String opts = optStatus.get(this.paper.getRow());
                    for (int i = 0;i<4;i++){
                        b[i].setSelected(opts.contains(this.b[i].getText()));
                    }
                }else {
                    for (int i=0;i<4;i++){
                        this.b[i].setSelected(false);
                    }
                }
                if (testNum == 1){
                    btn1.setEnabled(false);
                }
            }
        }
        if (e.getSource() == btn2){
            if (testNum == testsSum){
                btn2.setEnabled(false);
            }else {
                testNum++;
                this.btn1.setEnabled(true);
                if (resultJudge()){
                    scoreMap.put(paper.getRow(),oneScore);
                }
                this.paper = MyController.getTestByRow(testNum-1);          // 更新试卷
                String ms = "第"+testNum+"题/共"+testsSum+"题";
                this.label2.setText(ms);
                this.area.setText("【"+paper.getTestsType()+"】"+paper.getStem()+"\n"+paper.getOptions());
                if (optStatus.containsKey(this.paper.getRow()) && (!optStatus.get(this.paper.getRow()).equals(""))){
                    String opts = optStatus.get(this.paper.getRow());
                    for (int i = 0;i<4;i++){
                        b[i].setSelected(opts.contains(this.b[i].getText()));
                    }
                }else {
                    for (int i=0;i<4;i++){
                        this.b[i].setSelected(false);
                    }
                }
                if (testNum == testsSum){
                    btn2.setEnabled(false);
                }
            }
        }
        if (e.getSource() == btn3){
            Object[] options = { "确认", "取消" };
            int n = JOptionPane.showOptionDialog(null, "考试时间未结束，确认交卷吗？", "交卷提醒", JOptionPane.DEFAULT_OPTION,
                    JOptionPane.WARNING_MESSAGE, null, options, options[0]);
            if (n == 0){
                if (resultJudge()){
                    scoreMap.put(paper.getRow(),oneScore);
                }
                getSumScore();      // 获取总成绩
                JOptionPane.showMessageDialog(null, "您的测试成绩为："+this.score);
                ReHome();
            }

        }
    }
}
